package com.wonders.ghy.juc.单例模式多线程不安全;
/**
 *  懒汉式 只有在getInstance的时候才会创建单例
 */
public class SingletonDemo {
    private static volatile SingletonDemo instance = null;
    private SingletonDemo(){
        System.out.println(Thread.currentThread().getName()+"\t我是构造方法SingletonDemo()!");
    }
    /**
     * 如果想要实现单例模式多线程安全这里第一种方式可以在方法上加synchronized
     * 但是如果加了synchronized相当于加了重锁 太影响性能
     * 所以采取DCL(double check Lock双端检锁机制)
     * 打个比方.上厕所 卫生间确认没人了 进去了锁上门之后 我再确认一下卫生间里是否有人 没人才开始"干活"
     *
     * 但是!还是不对!因为存在多线程下的指令重排.有极小部分的几率还是会出错!所以要在单例前加volatile
     */
    public static SingletonDemo getInstance(){
        if (instance == null) {
            synchronized (SingletonDemo.class){
                if (instance == null) {
                    instance=new SingletonDemo();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        // 比较内存地址
//        System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
//        System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
//        System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());

        for (int i = 0; i < 30; i++) {
            new Thread(()->{SingletonDemo.getInstance();},String.valueOf(i)).start();
        }
    }
}
